﻿using Nasty.Core.LoadParams;
using Nasty.Core;
using Nasty.Core.Repository;
using Nasty.Core.SuperExtension;
using Nasty.SystemModule.Areas.User.Model;
using Nasty.SystemModule.Areas.User.Params;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using Nasty.Core.Log;

namespace Nasty.SystemModule.User
{
    public interface IUserRepository : IRepository<Nasty.Core.Entity.System.User>
    {
        public Nasty.Core.Entity.System.User GetUser(string id);

        public ResultData<Nasty.Core.Entity.System.User> SaveUser(UserModel model);

        public ResultData<string> InitSA(string password);

        public Nasty.Core.Entity.System.User GetUserByAccount(string account);

        public Nasty.Core.Entity.System.User GetUserByAccount(string account, string password);

        public ResultData<string> SaveUserRole(SaveUserRoleModel model);

        public Nasty.Core.Entity.System.User GetDeepUser(string id);

        public PageData<Nasty.Core.Entity.System.User> GetUserPage(GetUserPageParams @params);

        public ResultData<string> DeleteUser(string id);

        public List<Nasty.Core.Entity.System.User> GetUsers(GetUsersParams @params);
    }

    public class UserRepository : SqlRepository<Nasty.Core.Entity.System.User>, IUserRepository
    {
        public UserRepository(SqlSugarClient db) : base(db)
        {
            //db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.Department));
            //db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.DepartmentUser));
            //db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.Dictionary));
            //db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.Permission));
            //db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.PermissionGroup));
            //db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.Post));
            //db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.Role));
            //db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.RolePermission));
            //db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.SerialNumberConfig));
            //db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.ThirdParty));
            //db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.User));
            //db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.UserMessage));
            //db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.UserRole));
        }

        public Nasty.Core.Entity.System.User GetUser(string id)
        {
            return this.Db.Queryable<Nasty.Core.Entity.System.User>().IncludesAllFirstLayer().InSingle(id);
        }

        public Nasty.Core.Entity.System.User GetUserByAccount(string account)
        {
            return this.Db.Queryable<Nasty.Core.Entity.System.User>().Where(it => it.Account == account).IncludesAllFirstLayer().First();
        }

        public Nasty.Core.Entity.System.User GetUserByAccount(string account, string password)
        {
            return this.Db.Queryable<Nasty.Core.Entity.System.User>().Where(it => it.Account == account && it.Password == password).First();
        }

        public Nasty.Core.Entity.System.User GetDeepUser(string id)
        {
            return this.Db.Queryable<Nasty.Core.Entity.System.User>().IncludesAllFirstLayer()
                .Includes((t) => t.Roles, (s) => s.Permissions)
                .Includes((t) => t.Departments, (s) => s.Role, (r) => r.Permissions)
                .InSingle(id);
        }

        public void InitTable()
        {
            // 查询是否存在 SysQuartzTask 表
            bool isExist = this.Db.DbMaintenance.GetTableInfoList()
                .Any(t => t.Name.Equals("SysUser", StringComparison.OrdinalIgnoreCase));

            if (isExist) return;

            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.Flow.Flow));
            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.Flow.FlowConfig));
            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.Flow.FlowConfigNode));
            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.Flow.FlowLog));
            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.Flow.FlowNode));


            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.ActionLog));
            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.Department));
            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.DepartmentUser));
            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.Dictionary));
            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.Permission));
            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.PermissionGroup));
            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.Post));
            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.Role));
            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.RolePermission));
            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.SerialNumberConfig));
            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.ThirdParty));
            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.User));
            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.UserMessage));
            this.Db.CodeFirst.InitTables(typeof(Nasty.Core.Entity.System.UserRole));
        }

        public ResultData<string> InitSA(string password)
        {
            InitTable();

            var result = new ResultData<string>();
            try
            {
      
                Db.BeginTran();
                var isAny = Db.Queryable<Nasty.Core.Entity.System.User>().Where((t) => t.Account == "sa").Any();
                if (isAny)
                {
                    result.IsSuccess = false;
                    result.Message = "sa账号已存在!";
                    return result;
                }

 

                var user = new Nasty.Core.Entity.System.User()
                {
                    Id = SnowFlakeSingle.Instance.NextId().ToString(),
                    Name = "超级管理员",
                    Account = "sa",
                    Password = password,
                };

                var role = new Nasty.Core.Entity.System.Role()
                {
                    Id = SnowFlakeSingle.Instance.NextId().ToString(),
                    Name = "超级管理员",
                    Code = "Admin",
                    Type = Core.Entity.System.RoleType.System,
                };


                Db.Add(user);
                Db.Add(role);

                user.Roles = new List<Core.Entity.System.Role>() { role };
                Db.UpdateNav(user).Include((t) => t.Roles).ExecuteCommand();

                Db.CommitTran();
                result.IsSuccess = true;
                return result;
            }
            catch (Exception ex)
            {
                Db.RollbackTran();
                result.IsSuccess = false;
                result.Message = ex.Message;
                return result;
            }
        }

        public ResultData<string> SaveUserRole(SaveUserRoleModel model)
        {
            var result = new ResultData<string>();
            try
            {

                var user = Db.Queryable<Nasty.Core.Entity.System.User>().InSingle(model.UserId);
                if (user == null)
                {
                    result.IsSuccess = false;
                    result.Message = "账号不存在!";
                    return result;
                }

                if (model.RoleIds.Count > 0)
                {
                    var roles = Db.Queryable<Nasty.Core.Entity.System.Role>().In(model.RoleIds).ToList();
                    user.Roles = roles;
                    Db.UpdateNav(user).Include((t) => t.Roles).ExecuteCommand();
                }

                result.IsSuccess = true;
                return result;
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = ex.Message;
                return result;
            }
        }

        public PageData<Nasty.Core.Entity.System.User> GetUserPage(GetUserPageParams @params)
        {
            int totalPage = 0;
            int total = 0;
            var pageData = new PageData<Nasty.Core.Entity.System.User>();

            var _SQLExpress = Db.Queryable<Nasty.Core.Entity.System.User>().IncludesAllFirstLayer();

            if (!string.IsNullOrEmpty(@params.Name)) _SQLExpress.Where((t) => t.Name.Contains(@params.Name));
            if (!string.IsNullOrEmpty(@params.Account)) _SQLExpress.Where((t) => t.Account.Contains(@params.Account));
            if (@params.RoleIds != null) _SQLExpress.Where((t) => t.Roles.Any((r) => @params.RoleIds.Contains(r.Id)));
            if (@params.DepartmentIds != null) _SQLExpress.Where((t) => t.Departments.Any((d) => @params.DepartmentIds.Contains(d.Id)));

            _SQLExpress = _SQLExpress.OrderBy((t) => t.CreateTime, OrderByType.Desc);
            var data = _SQLExpress.ToPageList(@params.Current, @params.PageSize, ref total, ref totalPage);

            pageData.Total = total;
            pageData.TotalPage = totalPage;
            pageData.Data = data;

            pageData.Current = @params.Current;
            pageData.PageSize = @params.PageSize;
            return pageData;
        }

        public List<Nasty.Core.Entity.System.User> GetUsers(GetUsersParams @params)
        {

            var _SQLExpress = Db.Queryable<Nasty.Core.Entity.System.User>().IncludesAllFirstLayer();

            if (!string.IsNullOrEmpty(@params.Name)) _SQLExpress.Where((t) => t.Name.Contains(@params.Name));
            if (!string.IsNullOrEmpty(@params.Account)) _SQLExpress.Where((t) => t.Account.Contains(@params.Account));

            _SQLExpress = _SQLExpress.OrderBy((t) => t.CreateTime, OrderByType.Desc);

            return _SQLExpress.ToList();
        }

        public ResultData<Nasty.Core.Entity.System.User> SaveUser(UserModel model)
        {
            var result = new ResultData<Nasty.Core.Entity.System.User>();
            try
            {
                var user = Db.Save<Nasty.Core.Entity.System.User>(model);
                result.IsSuccess = true;
                result.Data = user;
                return result;
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = ex.Message;
                return result;
            }
        }

        public ResultData<string> DeleteUser(string id)
        {
            var result = new ResultData<string>();
            try
            {
                Db.Delete<Nasty.Core.Entity.System.User>(id);
                result.IsSuccess = true;
                return result;
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = ex.Message;
                return result;
            }
        }
    }
}
